import { Checkbox } from 'antd';
import React from 'react';
import { RightOutlined } from '@ant-design/icons';
import { useState, useEffect } from "react"

import "./index.css"

export default function Cascader(props) {
    const [panelList, setPanelList] = useState([])
    const [clickedIds, setClickedIds] = useState([])

    useEffect(() => {
        const { dataSource, values = [] } = props;
        addDataLevel(dataSource || [], values);
        setClickedIds([dataSource[0].value]);
        panelList[0] = dataSource;
        addPanelList(dataSource[0]);
    }, [])

    /**
     * 对数据添加字段
     * @param {[]} data 数据源
     * @param {string[] | number[]} values 默认选中的values
     * @param {number} level 数据层级
     * @param {{}} parent 子级对应的父级数据
     */
    const addDataLevel = (data, values = [], level = 0, parent = {}) => {
        data.map(item => {
            item.level = level;
            item.parent = level == 0 ? {} : parent;
            item.checked = values.includes(item.value)
            item.isLast = item.children && item.children.length ? false : true;
            if (item.children && item.children.length) {
                addDataLevel(item.children, values, level + 1, item)
            }
        })
    }

    /**
     * 父级选中时，子级随之选中，反之亦然
     * @param {Array} childData 子级数据
     * @param {Boolean} checkSate 选中状态
     */
    const setChildChecked = (childData = [], checkSate = false) => {
        if (Array.isArray(childData) && childData.length) {
            return childData.map(item => {
                item.checked = checkSate;
                item.indeterminate = false;
                !item.isLast && setChildChecked(item.children, checkSate);
            })
        }
    }

    /**
     * 子级全部选中时，其相应的父级也要选中
     * @param {{}} parentData 子级对应的父级
     */
    const setParentCheck = (parentData = {}) => {
        let isChecked = parentData.children && parentData.children.every(x => x.checked);//全选
        let isIndeterminate = parentData.children && parentData.children.some(x => x.checked || x.indeterminate); //半选                                              
        parentData.checked = isChecked;
        parentData.indeterminate = !isChecked && isIndeterminate;
        parentData.parent && setParentCheck(parentData.parent);
    }

    /**
     * 通过点击事件展示下一级panel的数据
     * @param {object} panelData 
     */
    const addPanelList = (panelData = {}) => { 
        const panel = (data, level) => {
            if (!data.isLast) {
                panelList[data.level + 1] = data.children || [];
                clickedIds[data.level] = data.value;
                !data.isLast && panel(data.children[0], level + 1);
            }
        }

        panel(panelData, panelData.level);
        setClickedIds(clickedIds);
        setPanelList([...panelList]);
    }

    const showPanelContent = (data) => {
        return <ul role="group">
            {
                data && data.map(item => {
                    return <li role='item' className={clickedIds.includes(item.value) ? "li-checked" : 'li-not-checked'}>
                        <Checkbox checked={item.checked} indeterminate={item.indeterminate}
                            onChange={(e) => {
                                let check = e.target.checked;
                                item.checked = check;
                                item.indeterminate = false;
                                !item.isLast && setChildChecked(item.children, check)
                                item.level != 0 && setParentCheck(item.parent)

                                addPanelList(item)
                            }} >{item.title}</Checkbox>
                        {!item.isLast && <span className='icon-right' onClick={() => { addPanelList(item) }}><RightOutlined /></span> }
                    </li>
                })
            }
        </ul>
    }

    return <React.Fragment>
        <div className='cascader'>
            {
                panelList.map(item => showPanelContent(item))
            }
        </div>
    </React.Fragment>
}